/* 
 * Copyright (C) 2001-2003 Jacek Sieka, j_s@telia.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */


#include "stdafx.h"
#include "../client/DCPlusPlus.h"
#include "Resource.h"

#include "MainFrm.h"
#include "AboutDlg.h"
#include "HubFrame.h"
#include "SearchFrm.h"
#include "PublicHubsFrm.h"
#include "PropertiesDlg.h"
#include "UsersFrame.h"
#include "DirectoryListingFrm.h"
#include "FavoritesFrm.h"
#include "NotepadFrame.h"
#include "QueueFrame.h"
#include "SpyFrame.h"
#include "FinishedFrame.h"
#include "ADLSearchFrame.h"
#include "FinishedULFrame.h"
#include "TextFrame.h"
#include "StatsFrame.h"
//#include "UploadQueueFrame.h"
// CDM EXTENSION BEGINS
#include "CDMDebugFrame.h"
#include "WinampFrame.h"
#include "ScriptEditorFrame.h"
#include "Winamp.h"
#include "ClientVersionFrame.h"
// pothead starts svn171 (dc++ code)
#include "LineDlg.h"
// pothead ends
// CDM EXTENSION ENDS

#include "../client/LogManager.h"

#include "../client/ConnectionManager.h"
#include "../client/DownloadManager.h"
#include "../client/UploadManager.h"
#include "../client/StringTokenizer.h"
#include "../client/SimpleXML.h"
#include "../client/ShareManager.h"

#include "../client/HashManager.h"
#include "InputBox.h"

MainFrame::~MainFrame() {
	m_CmdBar.m_hImageList = NULL;

	images.Destroy();
	largeImages.Destroy();
	largeImagesHot.Destroy();

	WinUtil::uninit();
}

DWORD WINAPI MainFrame::stopper(void* p) {
	MainFrame* mf = (MainFrame*)p;
	HWND wnd, wnd2 = NULL;

	while( (wnd=::GetWindow(mf->m_hWndMDIClient, GW_CHILD)) != NULL) {
		if(wnd == wnd2) 
			Sleep(100);
		else { 
			::PostMessage(wnd, WM_CLOSE, 0, 0);
			wnd2 = wnd;
		}
	}

	shutdown();
	
	mf->PostMessage(WM_CLOSE);	
	return 0;
}

LRESULT MainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {

	TimerManager::getInstance()->addListener(this);
	QueueManager::getInstance()->addListener(this);
	LogManager::getInstance()->addListener(this);
	//Sulan start svn 46
	ClientVersionManager::getInstance()->addListener(this);
	//End

	//Sulan start svn108, R2 modified svn112
	File::ensureDirectory(Util::getAppPath() + "\\MyFilelists\\");
	ShareManager::getInstance()->setDirty();
	if(BOOLSETTING(REFRESH_FILELIST_ON_STARTUP)) {
		ShareManager::getInstance()->refresh(true, true, true, false);
	}else{
		ShareManager::getInstance()->refresh(false, true, false, true);
	}
	//End

	WinUtil::init(m_hWnd);

	LoadLibraryA("RICHED20.DLL");

	// Register server socket message
	WSAAsyncSelect(ConnectionManager::getInstance()->getServerSocket().getSocket(),
		m_hWnd, SERVER_SOCKET_MESSAGE, FD_ACCEPT);

	trayMessage = RegisterWindowMessage(_T("TaskbarCreated"));

	TimerManager::getInstance()->start();

	// Set window name
	// CDM EXTENSION BEGINS
	string wintxt = "-[ " APPNAME " " DISPLAYVERSIONSTRING " ]- -[ " + Util::getOsVersion() + " ]-";
	if (!SETTING(NICK).empty()) { wintxt += " -[ " + SETTING(NICK) + " ]-"; }
	SetWindowText(wintxt.c_str());
	// CDM EXTENSION ENDS

	// Load images
	// create command bar window
	HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);

	m_hMenu = WinUtil::mainMenu;

	// attach menu
	m_CmdBar.AttachMenu(m_hMenu);
	// load command bar images
	images.CreateFromImage(IDB_TOOLBAR, 16, 16, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
	m_CmdBar.m_hImageList = images;

	m_CmdBar.m_arrCommand.Add(ID_FILE_CONNECT);
	m_CmdBar.m_arrCommand.Add(ID_FILE_RECONNECT);
	m_CmdBar.m_arrCommand.Add(IDC_FOLLOW);
	m_CmdBar.m_arrCommand.Add(IDC_FAVORITES);
	m_CmdBar.m_arrCommand.Add(IDC_FAVUSERS);
	m_CmdBar.m_arrCommand.Add(IDC_QUEUE);
	m_CmdBar.m_arrCommand.Add(IDC_FINISHED);
	//m_CmdBar.m_arrCommand.Add(IDC_VIEW_UPLOAD_QUEUE);
	m_CmdBar.m_arrCommand.Add(IDC_FINISHED_UL);
	m_CmdBar.m_arrCommand.Add(ID_FILE_SEARCH);
	m_CmdBar.m_arrCommand.Add(IDC_FILE_ADL_SEARCH);
	m_CmdBar.m_arrCommand.Add(IDC_SEARCH_SPY);
	m_CmdBar.m_arrCommand.Add(IDC_OPEN_FILE_LIST);
	m_CmdBar.m_arrCommand.Add(ID_FILE_SETTINGS);
	m_CmdBar.m_arrCommand.Add(IDC_NOTEPAD);
	m_CmdBar.m_arrCommand.Add(IDC_NET_STATS);
	// CDM EXTENSION BEGINS
	m_CmdBar.m_arrCommand.Add(IDC_CDMDEBUG_WINDOW);
	m_CmdBar.m_arrCommand.Add(IDC_WINAMP_WINDOW);
	m_CmdBar.m_arrCommand.Add(IDC_SCRIPT_EDITOR);
	//Sulan start svn 44
	m_CmdBar.m_arrCommand.Add(IDC_CLIENT_VERSION_WINDOW);
	//End
	// CDM EXTENSION ENDS
	m_CmdBar.m_arrCommand.Add(ID_WINDOW_CASCADE);
	m_CmdBar.m_arrCommand.Add(ID_WINDOW_TILE_HORZ);
	m_CmdBar.m_arrCommand.Add(ID_WINDOW_TILE_VERT);
	m_CmdBar.m_arrCommand.Add(ID_WINDOW_MINIMIZE_ALL);
	
	// remove old menu
	SetMenu(NULL);

	HWND hWndToolBar = createToolbar(3);

	CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
	AddSimpleReBarBand(hWndCmdBar);
	AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
	CreateSimpleStatusBar();
	// CDM EXTENSION BEGINS
	hWndToolBar = createSmallToolbar();
	AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
	// CDM EXTENSION ENDS

	ctrlStatus.Attach(m_hWndStatusBar);
	ctrlStatus.SetSimple(FALSE);
	// pothead extension starts (r2 code) #12 svn 103
	//int w[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	int w[7] = { 0, 0, 0, 0, 0, 0, 0 };
	//ctrlStatus.SetParts(10, w);
	ctrlStatus.SetParts(7, w);
	// pothead extension ends
	statusSizes[0] = WinUtil::getTextWidth(STRING(AWAY), ::GetDC(ctrlStatus.m_hWnd)); // for "AWAY" segment
	CToolInfo ti(TTF_SUBCLASS | TTF_DI_SETITEM, ctrlStatus.m_hWnd);

	ctrlLastLines.Create(ctrlStatus.m_hWnd, rcDefault, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, WS_EX_TOPMOST);
	ctrlLastLines.AddTool(&ti);
	ctrlLastLines.SetDelayTime(TTDT_AUTOPOP, 30000); 

	CreateMDIClient();
	m_CmdBar.SetMDIClient(m_hWndMDIClient);
	WinUtil::mdiClient = m_hWndMDIClient;

	ctrlTab.Create(m_hWnd, rcDefault);
	WinUtil::tabCtrl = &ctrlTab;

	transferView.Create(m_hWnd);

	SetSplitterPanes(m_hWndMDIClient, transferView.m_hWnd);
	SetSplitterExtendedStyle(SPLIT_PROPORTIONAL);
	m_nProportionalPos = 8000;

	UIAddToolBar(hWndToolBar);
	UISetCheck(ID_VIEW_TOOLBAR, 1);
	// CDM EXTENSION BEGINS
	UISetCheck(IDC_TOGGLE_TOOLBAR, 1);
	// CDM EXTENSION ENDS
	UISetCheck(ID_VIEW_STATUS_BAR, 1);

	// register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

	c->addListener(this);
	if (!BOOLSETTING(BLOCK_VERSION_POPUPS)) {
// DanShUK 28/01/06
		const string sTodaysDate = Util::getDateString();
		if (SETTING(DCDMUPDATE_LASTCHECK).find(sTodaysDate) == string::npos) {
// flow84 fix start svn 82
			c->downloadFile(GETVERSION "dcdmversion.xml");
// flow84 fix end
			SettingsManager::getInstance()->set(SettingsManager::DCDMUPDATE_LASTCHECK, sTodaysDate);
		}
// End DanShUK
	}

	// ZoneAlarm - ref: http://www.unixwiz.net/backstealth/
	if (FindWindow(NULL, _T("ZoneAlarm")) || FindWindow(NULL, _T("ZoneAlarm Pro"))) {
		int times_detected = SETTING(ZONEALARM_DETECTIONS);
		if (times_detected % 13 == 0) {
			::MessageBox(m_hWnd, _T("ZoneAlarm has been detected on your computer. It is frequently responsible for corrupted ")
				_T("downloads and is the cause of many \"rollback inconsistency\" errors. Please uninstall it and use an ")
				_T("alternate product. "), _T(APPNAME) _T(" ") _T(DISPLAYVERSIONSTRING), MB_OK | MB_ICONERROR);
		}
		SettingsManager::getInstance()->set(SettingsManager::ZONEALARM_DETECTIONS, ++times_detected);
	}

	if(BOOLSETTING(OPEN_PUBLIC))
		PostMessage(WM_COMMAND, ID_FILE_CONNECT);
	if(BOOLSETTING(OPEN_QUEUE))
		PostMessage(WM_COMMAND, IDC_QUEUE);
	if(BOOLSETTING(OPEN_FAVORITE_HUBS))
		PostMessage(WM_COMMAND, IDC_FAVORITES);
	if(BOOLSETTING(OPEN_FINISHED_DOWNLOADS))
		PostMessage(WM_COMMAND, IDC_FINISHED);
	if(BOOLSETTING(OPEN_NOTEPAD))
		PostMessage(WM_COMMAND, IDC_NOTEPAD);
	// CDM EXTENSION BEGINS
	if(!BOOLSETTING(SHOW_WINAMP_CONTROL))
		PostMessage(WM_COMMAND, IDC_TOGGLE_TOOLBAR);
	// CDM EXTENSION ENDS
//	if(BOOLSETTING(OPEN_UPLOAD_QUEUE))
		//PostMessage(WM_COMMAND, IDC_VIEW_UPLOAD_QUEUE);

	if(!(GetAsyncKeyState(VK_SHIFT) & 0x8000))
		PostMessage(WM_SPEAKER, AUTO_CONNECT);

	PostMessage(WM_SPEAKER, PARSE_COMMAND_LINE);

	File::ensureDirectory(SETTING(LOG_DIRECTORY));
	//Sulan fix
	File::ensureDirectory(Util::getAppPath() + "\\XML\\");
	//End
	// http://www.imperialnet.org/forum/viewtopic.php?t=1533
	startSocket();

	if(SETTING(NICK).empty()) {
		PostMessage(WM_COMMAND, IDC_HELP_README);
		PostMessage(WM_COMMAND, ID_FILE_SETTINGS);
	}
	// CDM EXTENSION BEGINS
	m_PictureWindow.SubclassWindow(m_hWndMDIClient);
	m_PictureWindow.m_nMessageHandler = CPictureWindow::BackGroundPaint;
	currentPic = SETTING(BACKGROUND_IMAGE);
	m_PictureWindow.Load(currentPic.c_str());
	// CDM EXTENSION ENDS
	// We want to pass this one on to the splitter...hope it get's there...
	bHandled = FALSE;
	return 0;
}

// CDM EXTENSION BEGINS
HWND MainFrame::createSmallToolbar() {
	CToolBarCtrl ctrlSmallToolbar;

	winampImages.CreateFromImage(IDB_WINAMP_CONTROL, 20, 15, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);

	ctrlSmallToolbar.Create(m_hWnd, NULL, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, 0, ATL_IDW_TOOLBAR);
	ctrlSmallToolbar.SetImageList(winampImages);

	const int numButtons = 12;

	TBBUTTON tb[numButtons];
	memset(tb, 0, sizeof(tb));
	int n = 0, bitmap = 0;

#define ADD_BUTTON(a) \
	tb[n].iBitmap = bitmap++; \
	tb[n].idCommand = a; \
	tb[n].fsState = TBSTATE_ENABLED; \
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE; \
	n++;

#define ADD_SEPERATOR() \
	tb[n].fsStyle = TBSTYLE_SEP; \
	n++;

	//Fix buttons
	// back play pause next stop volumeupp volume 50% volume down
	ADD_BUTTON(IDC_WINAMP_WINDOW)
	ADD_BUTTON(ID_WINAMP_SPAM)
	ADD_SEPERATOR()
	ADD_BUTTON(IDC_WINAMP_BACK)
	ADD_BUTTON(IDC_WINAMP_PLAY)	
	ADD_BUTTON(IDC_WINAMP_PAUSE)
	ADD_BUTTON(IDC_WINAMP_NEXT)
	ADD_BUTTON(IDC_WINAMP_STOP)
	ADD_BUTTON(IDC_WINAMP_VOL_UP)
	ADD_BUTTON(IDC_WINAMP_VOL_HALF)
	ADD_BUTTON(IDC_WINAMP_VOL_DOWN)
	ADD_SEPERATOR()

	ctrlSmallToolbar.SetButtonStructSize();
	ctrlSmallToolbar.AddButtons(numButtons, tb);
	ctrlSmallToolbar.AutoSize();

	return ctrlSmallToolbar.m_hWnd;
}

LRESULT MainFrame::onWinampButton(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	HWND hwndWinamp = FindWindow(_T("Winamp v1.x"), NULL);
	if(hwndWinamp) {
		switch(wID) {
			case IDC_WINAMP_BACK: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_BUTTON1, 0); break;
			case IDC_WINAMP_PLAY: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_BUTTON2, 0); break;
			case IDC_WINAMP_STOP: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_BUTTON4, 0); break;
			case IDC_WINAMP_PAUSE: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_BUTTON3, 0); break;	
			case IDC_WINAMP_NEXT: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_BUTTON5, 0); break;
			case IDC_WINAMP_VOL_UP: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_VOLUMEUP, 0); break;
			case IDC_WINAMP_VOL_DOWN: SendMessage(hwndWinamp, WM_COMMAND, WINAMP_VOLUMEDOWN,0); break;
			case IDC_WINAMP_VOL_HALF: SendMessage(hwndWinamp, WM_WA_IPC, 123, IPC_SETVOLUME); break;
		}
	}
	return 0;
}
// CDM EXTENSION ENDS

void MainFrame::startSocket() {
	SearchManager::getInstance()->disconnect();
	ConnectionManager::getInstance()->disconnect();

	if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE) {

		short lastPort = (short)SETTING(IN_PORT);
		short firstPort = lastPort;

		while(true) {
			try {
				ConnectionManager::getInstance()->setPort(lastPort);
				WSAAsyncSelect(ConnectionManager::getInstance()->getServerSocket().getSocket(), m_hWnd, SERVER_SOCKET_MESSAGE, FD_ACCEPT);
				SearchManager::getInstance()->setPort(static_cast<short>(SETTING(SEARCH_IN_PORT)?SETTING(SEARCH_IN_PORT):SETTING(IN_PORT)));
				break;
			} catch(const Exception& e) {
				dcdebug("MainFrame::OnCreate caught %s\n", e.getError().c_str());
				short newPort = (short)((lastPort == 32000) ? 1025 : lastPort + 1);
				SettingsManager::getInstance()->setDefault(SettingsManager::IN_PORT, newPort);
				if(SETTING(IN_PORT) == lastPort || (firstPort == newPort)) {
					// Changing default didn't change port, a fixed port must be in use...(or we
					// tried all ports
					TCHAR* buf = new TCHAR[STRING(PORT_IS_BUSY).size() + 8];
					_stprintf(buf, CSTRING(PORT_IS_BUSY), SETTING(IN_PORT));
					MessageBox(buf, _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_ICONSTOP | MB_OK);
					delete[] buf;
					break;
				}
				lastPort = newPort;
			}
		}
	}
	startUPnP();
}

HWND MainFrame::createToolbar(const int notepad) {
	CToolBarCtrl ctrlToolbar;
	largeImages.CreateFromImage(IDB_TOOLBAR20, 20, 16, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);
	largeImagesHot.CreateFromImage(IDB_TOOLBAR20_HOT, 20, 16, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_SHARED);

	ctrlToolbar.Create(m_hWnd, NULL, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, 0, ATL_IDW_TOOLBAR);
	ctrlToolbar.SetImageList(largeImages);
	ctrlToolbar.SetHotImageList(largeImagesHot);

	const int numButtons = 127;

	TBBUTTON tb[numButtons];
	memset(tb, 0, sizeof(tb));
	int n = 0, bitmap = 0;

	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = ID_FILE_CONNECT;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = ID_FILE_RECONNECT;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_FOLLOW;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_FAVORITES;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_FAVUSERS;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_QUEUE;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_FINISHED;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

/*	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_VIEW_UPLOAD_QUEUE;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;*/

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_FINISHED_UL;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = ID_FILE_SEARCH;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_FILE_ADL_SEARCH;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_SEARCH_SPY;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_OPEN_FILE_LIST;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
		
	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = ID_FILE_SETTINGS;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	int tmp = bitmap++;
	int i = 0;
	for (; i <=  notepad; ++i){
		n++;
		tb[n].iBitmap = tmp;
		tb[n].idCommand = (IDC_NOTEPAD + i);
		tb[n].fsState = TBSTATE_ENABLED;
		tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
	}

	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_SCRIPT_EDITOR;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	n++;
	tb[n].fsStyle = TBSTYLE_SEP;

	// CDM EXTENSION BEGINS
	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_TOGGLE_TOOLBAR;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;

	//Sulan start svn 46
	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_CLIENT_VERSION_WINDOW;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
	//Sulan start 144
	n++;
	tb[n].iBitmap = bitmap++;
	tb[n].idCommand = IDC_START_CHECKING;
	tb[n].fsState = TBSTATE_ENABLED;
	tb[n].fsStyle = TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE;
	//End
	
	// CDM EXTENSION ENDS
n++;
	ctrlToolbar.SetButtonStructSize();
	ctrlToolbar.AddButtons(n, tb);
	ctrlToolbar.AutoSize();

	return ctrlToolbar.m_hWnd;
}

LRESULT MainFrame::onSpeaker(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) {
	
	if(wParam == DOWNLOAD_LISTING) {
		HWND activeChild = MDIGetActive();
		DirectoryListInfo* i = (DirectoryListInfo*)lParam;
		DirectoryListingFrame::openWindow(i->file, i->user, i->start);
		delete i;
		if (activeChild && ::IsWindow(activeChild)) {
			if(::IsIconic(activeChild))
				::ShowWindow(activeChild, SW_RESTORE);
			MDIActivate(activeChild);
		}
	} else if(wParam == VIEW_FILE_AND_DELETE) {
		string* file = (string*)lParam;
		TextFrame::openWindow(*file);
		File::deleteFile(*file);
		delete file;
	} else if(wParam == STATS) {
		StringList& str = *(StringList*)lParam;
		if(ctrlStatus.IsWindow()) {
			HDC dc = ::GetDC(ctrlStatus.m_hWnd);
			bool u = false;
			ctrlStatus.SetText(1, str[0].c_str());
			// pothead extension starts #12 svn103
			//for(int i = 1; i < 9; i++) {
			for(int i = 1; i < 6; i++) {
			// pothead extension ends
				int w = WinUtil::getTextWidth(str[i], dc);
				
				if(statusSizes[i] < w) {
					statusSizes[i] = w;
					u = true;
				}
				ctrlStatus.SetText(i+1, str[i].c_str());
			}
			::ReleaseDC(ctrlStatus.m_hWnd, dc);
			if(u)
				UpdateLayout(TRUE);
		}
		delete &str;
	} else if(wParam == AUTO_CONNECT) {
		autoConnect(HubManager::getInstance()->getFavoriteHubs());
	} else if(wParam == PARSE_COMMAND_LINE) {
		parseCommandLine(GetCommandLine());
	} else if(wParam == STATUS_MESSAGE) {
		string* msg = (string*)lParam;
		if(ctrlStatus.IsWindow()) {
			string line = "[" + Util::getShortTimeString() + "] " + *msg;

			ctrlStatus.SetText(0, line.c_str());
			while(lastLinesList.size() + 1 > MAX_CLIENT_LINES)
				lastLinesList.erase(lastLinesList.begin());
			if (line.find('\r') == string::npos) {
				lastLinesList.push_back(line);
			} else {
				lastLinesList.push_back(line.substr(0, line.find('\r')));
			}
		}
		delete msg;
	}
	//Sulan start svn 46
	else if(wParam == OPEN_CVF) {
		ClientVersionFrame::openWindow();
	}

	return 0;
}

void MainFrame::parseCommandLine(const string& cmdLine)
{
	string::size_type i = 0;
	string::size_type j;

	if( (j = cmdLine.find("dchub://", i)) != string::npos) {
		i = j + 8;
		string server;
		string user;
		if( (j = cmdLine.find('/', i)) == string::npos) {
			server = cmdLine.substr(i);
		} else {
			server = cmdLine.substr(i, j-i);
			i = j + 1;
			if( (j = cmdLine.find_first_of("\\/ ", i)) == string::npos) {
				user = cmdLine.substr(i);
			} else {
				user = cmdLine.substr(i, j-i);
			}
		}

		if(!server.empty()) {
			HubFrame::openWindow(server);
		}
		if(!user.empty()) {
			try {
				QueueManager::getInstance()->addList(ClientManager::getInstance()->getUser(user), QueueItem::FLAG_CLIENT_VIEW);
			} catch(const Exception&) {
				// ...
			}
		}
// R2 extesnion begins svn126
	} else if( (j = cmdLine.find("magnet:?", i)) != string::npos) {
		i = j + 8;
		string tth;
		if( (j = cmdLine.find("xt=urn:tree:tiger:", i)) != string::npos) {
			tth = cmdLine.substr(j + 18, 39);
			if(Encoder::isBase32(tth.c_str()))
				SearchFrame::openWindow(tth, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_HASH);
		} else if( (j = cmdLine.find("xt=urn:bitprint:", i)) != string::npos) {
			i = j + 16;
			if( (j = cmdLine.find(".", i)) != string::npos) {
				tth = cmdLine.substr(j + 1, 39);
				if(Encoder::isBase32(tth.c_str()))
					SearchFrame::openWindow(tth, 0, SearchManager::SIZE_DONTCARE, SearchManager::TYPE_HASH);
			}
		}
// R2 extension ends svn126
	}
}

LRESULT MainFrame::onCopyData(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) {
	string cmdLine = (LPCSTR) (((COPYDATASTRUCT *)lParam)->lpData);
	parseCommandLine(Util::getAppName() + " " + cmdLine);
	return true;
}

LRESULT MainFrame::onOpenWindows(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	if ( IDC_NOTEPAD <= wID && IDC_NOTEPAD_END >= wID){
		int tmp = (wID - (IDC_NOTEPAD - 1));
		string ntmp = Util::toString(tmp);
		NotepadFrame::openWindow("Notepad" + ntmp);
		return 0;
	}

	return 0;
}

LRESULT MainFrame::OnFileSearch(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	SearchFrame::openWindow();
	return 0;
}	

LRESULT MainFrame::onFavorites(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	FavoriteHubsFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onFavoriteUsers(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	UsersFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onQueue(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	QueueFrame::openWindow();
	return 0;
}

LRESULT MainFrame::OnFileConnect(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	PublicHubsFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onSearchSpy(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	SpyFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onNetStats(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	StatsFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onFileADLSearch(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 
{
	ADLSearchFrame::openWindow();
	return 0;
}

//LRESULT MainFrame::onViewUploadQueue(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 
/*{
	UploadQueueFrame::openWindow();
	return 0;
}*/

//Sulan start svn 44
LRESULT MainFrame::onClientVersionWindow(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 
{
	ClientVersionFrame::openWindow();
	return 0;
}

//End

// CDM EXTENSION BEGINS
LRESULT MainFrame::onCDMDebugWindow(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 
{
	CDMDebugFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onWinampWindow(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 
{
	WinampFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onScriptEditor(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) 
{
	ScriptEditorFrame::openWindow();
	return 0;
}
// CDM EXTENSION ENDS
LRESULT MainFrame::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	CAboutDlg dlg;
	dlg.DoModal(m_hWnd);
	return 0;
}

LRESULT MainFrame::OnFileSettings(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	PropertiesDlg dlg(SettingsManager::getInstance());

	short lastPort = (short)SETTING(IN_PORT);
	int lastConn = SETTING(CONNECTION_TYPE);

	if(dlg.DoModal(m_hWnd) == IDOK)
	{
		SettingsManager::getInstance()->save();
		if(SETTING(CONNECTION_TYPE) != lastConn || SETTING(IN_PORT) != lastPort) {
			startSocket();
		}
		ClientManager::getInstance()->infoUpdated();
	}
	return 0;
}

void MainFrame::onHttpComplete(HttpConnection* /*aConn*/) {
	try {
		SimpleXML xml;
		xml.fromXML(versionInfo);
		xml.stepIn();
		if(xml.findChild("Version")) {
			if(atof(xml.getChildData().c_str()) > DCDMVERSIONFLOAT) {
				xml.resetCurrentChild();
				string url;
				if(xml.findChild("URL")) {
					url = xml.getChildData();
				}
				xml.resetCurrentChild();
				if(xml.findChild("Title")) {
					const string& title = xml.getChildData();
					xml.resetCurrentChild();
					if(xml.findChild("Message")) {
						if(url.empty()) {
							const string& msg = xml.getChildData();
							MessageBox(msg.c_str(), title.c_str(), MB_OK);
						} else {
							string msg = xml.getChildData() + "\r\n" + STRING(OPEN_DOWNLOAD_PAGE);
							if(MessageBox(msg.c_str(), title.c_str(), MB_YESNO) == IDYES) {
								WinUtil::openLink(url);
							}
						}
					}
				}
				xml.resetCurrentChild();
				if(xml.findChild("VeryOldVersion")) {
					if(atof(xml.getChildData().c_str()) >= DCDMVERSIONFLOAT) {
						string msg = xml.getChildAttrib("Message", "Your version of DC++ contains a serious bug that affects all users of the DC network or the security of your computer.");
						MessageBox((msg + "\r\nPlease get a new one at " + url).c_str());
						oldshutdown = true;
						PostMessage(WM_CLOSE);
					}
				}
				xml.resetCurrentChild();
				if(xml.findChild("BadVersions")) {
					xml.stepIn();
					while(xml.findChild("BadVersion")) {
						float v = static_cast<float>(atof(xml.getChildAttrib("Version").c_str()));
						if(v == DCDMVERSIONFLOAT) {
							string msg = xml.getChildAttrib("Message", "Your version of DC++ contains a serious bug that affects all users of the DC network or the security of your computer.");
							MessageBox((msg + "\r\nPlease get a new one at " + url).c_str());
							oldshutdown = true;
							PostMessage(WM_CLOSE);
						}
					}
				}
			}
		}
	} catch (const Exception&) {
		// ...
	}
}

LRESULT MainFrame::onServerSocket(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
	ConnectionManager::getInstance()->getServerSocket().incoming();
	return 0;
}

LRESULT MainFrame::onGetToolTip(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) {
	LPNMTTDISPINFO pDispInfo = (LPNMTTDISPINFO)pnmh;
	pDispInfo->szText[0] = 0;

	if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND))
	{
		int stringId = -1;
		switch(idCtrl) {
			case ID_FILE_CONNECT: stringId = ResourceManager::MENU_PUBLIC_HUBS; break;
			case ID_FILE_RECONNECT: stringId = ResourceManager::MENU_RECONNECT; break;
			case IDC_FOLLOW: stringId = ResourceManager::MENU_FOLLOW_REDIRECT; break;
			case IDC_FAVORITES: stringId = ResourceManager::MENU_FAVORITE_HUBS; break;
			case IDC_FAVUSERS: stringId = ResourceManager::MENU_FAVORITE_USERS; break;
			case IDC_QUEUE: stringId = ResourceManager::MENU_DOWNLOAD_QUEUE; break;
			case IDC_FINISHED: stringId = ResourceManager::FINISHED_DOWNLOADS; break;
			case IDC_FINISHED_UL: stringId = ResourceManager::FINISHED_UPLOADS; break;
			//case IDC_VIEW_UPLOAD_QUEUE: stringId = ResourceManager::UPLOAD_QUEUE; break;
			case ID_FILE_SEARCH: stringId = ResourceManager::MENU_SEARCH; break;
			case IDC_FILE_ADL_SEARCH: stringId = ResourceManager::MENU_ADL_SEARCH; break;
			case IDC_SEARCH_SPY: stringId = ResourceManager::MENU_SEARCH_SPY; break;
			case IDC_OPEN_FILE_LIST: stringId = ResourceManager::MENU_OPEN_FILE_LIST; break;
			case ID_FILE_SETTINGS: stringId = ResourceManager::MENU_SETTINGS; break;
//			case IDC_NOTEPAD: stringId = ResourceManager::MENU_NOTEPAD; break;
			case IDC_WINAMP_WINDOW: stringId = ResourceManager::MENU_WINAMP; break;
			case IDC_SCRIPT_EDITOR: stringId = ResourceManager::SCRIPT_EDITOR; break;
			// CDM EXTENSION BEGINS
			//Sulan start svn 46
			case IDC_CLIENT_VERSION_WINDOW: stringId = ResourceManager::CLIENT_VERSIONS; break;
			case IDC_START_CHECKING: stringId = ResourceManager::START_CHECKING; break;
			//End
			case IDC_WINAMP_BACK: stringId = ResourceManager::WINAMP_BACK; break;
			case IDC_WINAMP_PLAY: stringId = ResourceManager::WINAMP_PLAY; break;
			case IDC_WINAMP_PAUSE: stringId = ResourceManager::WINAMP_PAUSE; break;
			case IDC_WINAMP_NEXT: stringId = ResourceManager::WINAMP_NEXT; break;
			case IDC_WINAMP_STOP: stringId = ResourceManager::WINAMP_STOP; break;
			case IDC_WINAMP_VOL_UP: stringId = ResourceManager::WINAMP_VOL_UP; break;
			case IDC_WINAMP_VOL_HALF: stringId = ResourceManager::WINAMP_VOL_HALF; break;
			case IDC_WINAMP_VOL_DOWN: stringId = ResourceManager::WINAMP_VOL_DOWN; break;
			case IDC_TOGGLE_TOOLBAR: stringId = ResourceManager::TOGGLE_TOOLBAR; break;
			case ID_WINAMP_SPAM: stringId = ResourceManager::WINAMP_SPAM; break;
			
			// CDM EXTENSION ENDS
		}
		if ( IDC_NOTEPAD <= idCtrl && IDC_NOTEPAD_END >= idCtrl){
			int tmp = (idCtrl - (IDC_NOTEPAD - 1));
			string ntmp = Util::toString(tmp);
			stringId = ResourceManager::MENU_NOTEPAD;
			if(stringId != -1) {
				_tcsncpy(pDispInfo->lpszText, Text::toT("Notepad " + ntmp).c_str(), 79);
			//pDispInfo->uFlags |= TTF_DI_SETITEM;
			}
		}else{
			if(stringId != -1) {
				_tcsncpy(pDispInfo->lpszText, CTSTRING_I((ResourceManager::Strings)stringId), 79);
				pDispInfo->uFlags |= TTF_DI_SETITEM;
			}
		}
	} else { // if we're really in the status bar, this should be detected intelligently
		lastLines.clear();
		for(StringIter i = lastLinesList.begin(); i != lastLinesList.end(); ++i) {
			lastLines += *i;
			lastLines += "\r\n";
		}
		if(lastLines.size() > 2) {
			lastLines.erase(lastLines.size() - 2);
		}
		pDispInfo->lpszText = const_cast<TCHAR*>(lastLines.c_str());
	}
	return 0;
}

void MainFrame::autoConnect(const FavoriteHubEntry::List& fl) {
	for(FavoriteHubEntry::List::const_iterator i = fl.begin(); i != fl.end(); ++i) {
		FavoriteHubEntry* entry = *i;
		if(entry->getConnect())
			HubFrame::openWindow(entry->getServer(), entry->getNick(), entry->getPassword(), entry->getUserDescription()
			// CDM EXTENSION BEGINS FAVS
			//Add to favs
			, entry->getRawOne()
			, entry->getRawTwo()
			, entry->getRawThree()
			, entry->getRawFour()
			, entry->getRawFive()
			, entry->getRawSix()
			, entry->getRawSeven()
			, entry->getRawEight()
			, entry->getRawNine()
			, entry->getRawTen()
			, entry->getOpChat()
			, entry->getUserIp()
			, entry->getCheckClients()
			, entry->getCheckFilelists()
			, entry->getCheckFakeShare()
			, entry->getCheckOnConnect()
			//Gabberworld start
			, entry->getCountryCodeCheck()
			, entry->getCountryCodeRaw()
			//Sulan start
			, entry->getProtectedUsers()
			, entry->getHideShare()
			//Sulan start 28
			, entry->getTrigger()
			//Sulan start svn86
			, entry->getLogChat()
			//Sulan start svn101
			, entry->getColumnOrder()
			, entry->getColumnWidth()
			, entry->getColumnVisible()
			//Sulan start svn124
			, entry->getWindowPosX()
			, entry->getWindowPosY()
			, entry->getWindowSizeX()
			, entry->getWindowSizeY()
			, entry->getWindowType()
			//End
			// pothead starts svn192 svn196 (sulan code)
			, entry->getHubMessage()
			, entry->getUseMyinfoDetect()
			, entry->getDisableRaws()
			// CDM EXTENSION ENDS
			);
	}
}

void MainFrame::updateTray(bool add /* = true */) {
	if(add) {
		NOTIFYICONDATA nid;
		nid.cbSize = sizeof(NOTIFYICONDATA);
		nid.hWnd = m_hWnd;
		nid.uID = 0;
		nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
		nid.uCallbackMessage = WM_APP + 242;
		nid.hIcon = (HICON)::LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
		_tcsncpy(nid.szTip, "DC++",64);
		nid.szTip[63] = '\0';
		lastMove = GET_TICK() - 1000;
		::Shell_NotifyIcon(NIM_ADD, &nid);
		trayIcon = true;
	} else {
		NOTIFYICONDATA nid;
		nid.cbSize = sizeof(NOTIFYICONDATA);
		nid.hWnd = m_hWnd;
		nid.uID = 0;
		nid.uFlags = 0;
		::Shell_NotifyIcon(NIM_DELETE, &nid);
		ShowWindow(SW_SHOW);
		trayIcon = false;		
	}
}

/**
 * @todo Fix so that the away mode is not reset if it was set manually...
 */
LRESULT MainFrame::onSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled) {
	if(wParam == SIZE_MINIMIZED) {
		if(BOOLSETTING(AUTO_AWAY)) {
			Util::setAway(true);
		}
		if(BOOLSETTING(MINIMIZE_TRAY)) {
			updateTray(true);
			ShowWindow(SW_HIDE);
		}
		maximized = IsZoomed() > 0;

	} else if( (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) ) {
		if(BOOLSETTING(AUTO_AWAY)) {
			Util::setAway(false);
		}
		if(trayIcon) {
			updateTray(false);
		}
	}
	
	bHandled = FALSE;
	return 0;
}

LRESULT MainFrame::onEndSession(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {
	if(c != NULL) {
		c->removeListener(this);
		delete c;
		c = NULL;
	}

	WINDOWPLACEMENT wp;
	wp.length = sizeof(wp);
	GetWindowPlacement(&wp);
	
	CRect rc;
	GetWindowRect(rc);
	
	if(wp.showCmd == SW_SHOW || wp.showCmd == SW_SHOWNORMAL) {
		SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_POS_X, rc.left);
		SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_POS_Y, rc.top);
		SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_SIZE_X, rc.Width());
		SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_SIZE_Y, rc.Height());
	}
	if(wp.showCmd == SW_SHOWNORMAL || wp.showCmd == SW_SHOW || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_MAXIMIZE)
		SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_STATE, (int)wp.showCmd);
	
	QueueManager::getInstance()->saveQueue();
	SettingsManager::getInstance()->save();
	
	return 0;
}

LRESULT MainFrame::OnClose(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) {
	if(c != NULL) {
		c->removeListener(this);
		delete c;
		c = NULL;
	}
	
	if(!closing) {
		if( oldshutdown ||(!BOOLSETTING(CONFIRM_EXIT)) || (MessageBox(CTSTRING(REALLY_EXIT), APPNAME " " VERSIONSTRING, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES) ) {
			string tmp1;
			string tmp2;

			WINDOWPLACEMENT wp;
			wp.length = sizeof(wp);
			GetWindowPlacement(&wp);

			CRect rc;
			GetWindowRect(rc);
			if(wp.showCmd == SW_SHOW || wp.showCmd == SW_SHOWNORMAL) {
				SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_POS_X, rc.left);
				SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_POS_Y, rc.top);
				SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_SIZE_X, rc.Width());
				SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_SIZE_Y, rc.Height());
			}
			if(wp.showCmd == SW_SHOWNORMAL || wp.showCmd == SW_SHOW || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_MAXIMIZE)
				SettingsManager::getInstance()->set(SettingsManager::MAIN_WINDOW_STATE, (int)wp.showCmd);

			ShowWindow(SW_HIDE);
			transferView.prepareClose();

			SearchManager::getInstance()->disconnect();
			ConnectionManager::getInstance()->disconnect();

			stopUPnP();

			DWORD id;
			stopperThread = CreateThread(NULL, 0, stopper, this, 0, &id);
			closing = true;
		}
		bHandled = TRUE;
	} else {
		// This should end immideately, as it only should be the stopper that sends another WM_CLOSE
		WaitForSingleObject(stopperThread, 60*1000);
		CloseHandle(stopperThread);
		stopperThread = NULL;
		bHandled = FALSE;
	}
	return 0;
}

LRESULT MainFrame::onLink(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	string site;
	bool isFile = false;
	switch(wID) {
	case IDC_HELP_README: site = Util::getAppPath() + "README.txt"; isFile = true; break;
	case IDC_HELP_CHANGELOG: site = Util::getAppPath() + "changelog.txt"; isFile = true; break;
	case IDC_HELP_HOMEPAGE: site = "http://dcplusplus.sourceforge.net"; break;
	case IDC_HELP_DOWNLOADS: site = "http://dcplusplus.sourceforge.net/index.php?page=download"; break;
	case IDC_HELP_FAQ: site = "http://dcplusplus.sourceforge.net/faq/faq.php?list=all&prog=1&lang=en"; break;
	case IDC_HELP_HELP_FORUM: site = "http://dcplusplus.sf.net/forum"; break;
	case IDC_HELP_DISCUSS: site = "http://dcplusplus.sf.net/forum"; break;
	case IDC_HELP_REQUEST_FEATURE: site = "http://sourceforge.net/tracker/?atid=427635&group_id=40287&func=browse"; break;
	case IDC_HELP_REPORT_BUG: site = "http://sourceforge.net/tracker/?atid=427632&group_id=40287&func=browse"; break;
	case IDC_HELP_DONATE: site = "https://www.paypal.com/xclick/business=j_s%40telia.com&item_name=DCPlusPlus&no_shipping=1&return=http%3A//dcplusplus.sf.net&cn=Greeting+%28and+forum+nick%3F%29&currency_code=EUR"; break;
	//Sulan start svn124
	case IDC_FORUM: site = "http://www.imperialnet.org/forum/"; break;
	case IDC_WEBSITE: site = "http://www.ukdnb.dsl.pipex.com/dcpluspluskcdm/index.html"; break;
	case IDC_ALT_WEBSITE: site = "http://flow84.no-ip.org/dcstuff/DCDM/"; break;
	case IDC_CHANGELOG: site = "http://flow84.no-ip.org/dcstuff/DCDM/?page=changelog"; break;
	//End
	default: dcassert(0);
	}

	if(isFile)
		WinUtil::openFile(site);
	else
		WinUtil::openLink(site);

	return 0;
}

LRESULT MainFrame::onImport(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	string file = Util::getAppPath() + "queue.config";
 	if(WinUtil::browseFile(file, m_hWnd, false) == IDOK) {
		try {
			QueueManager::getInstance()->importNMQueue(file);
 		} catch(const FileException&) {
			ctrlStatus.SetText(0, CSTRING(ERROR_OPENING_FILE));
 		}
 	} 
 	return 0;
}
 
void MainFrame::UpdateLayout(BOOL bResizeBars /* = TRUE */) {
	RECT rect;
	GetClientRect(&rect);
	// position bars and offset their dimensions
	UpdateBarsPosition(rect, bResizeBars);
	
	if(ctrlStatus.IsWindow() && ctrlLastLines.IsWindow()) {
		CRect sr;
		// pothead extension starts (r2 code) #12 svn103
		//int w[10];
		int w[7];
		// pothead extension ends
		ctrlStatus.GetClientRect(sr);
		// pothead extension starts (r2 code) #12 svn103
		//w[9] = sr.right - 16;
		w[6] = sr.right - 16;
		// pothead extension ends
#define setw(x) w[x] = max(w[x+1] - statusSizes[x], 0)
		// pothead extension starts (r2 code) #12 svn103
		//setw(8); setw(7); setw(6); setw(5); setw(4); setw(3); setw(2); setw(1); setw(0);
		setw(5); setw(4); setw(3); setw(2); setw(1); setw(0);
		//ctrlStatus.SetParts(10, w);
		ctrlStatus.SetParts(7, w);
		// pothead extension ends
		ctrlLastLines.SetMaxTipWidth(w[0]);
		ctrlLastLines.SetWindowPos(HWND_TOPMOST, sr.left, sr.top, sr.Width(), sr.Height(), SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
	}
	CRect rc = rect;
	rc.top = rc.bottom - ctrlTab.getHeight();
	if(ctrlTab.IsWindow())
		ctrlTab.MoveWindow(rc);
	
	CRect rc2 = rect;
	rc2.bottom = rc.top;
	SetSplitterRect(rc2);
}

static const char types[] = "File Lists\0*.DcLst;*.bz2;*.xml.bz2\0All Files\0*.*\0";

// R2 extension begins svn126
LRESULT MainFrame::onOpenFileList(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	string file;
	
	if(wID == IDC_OPEN_MY_LIST){
		file = ShareManager::getInstance()->getBZXmlFile();
		DirectoryListingFrame::openWindow(file, ClientManager::getInstance()->getUser("My List"));
				
		return 0;
	}
// R2 extension ends svn126
	if(WinUtil::browseFile(file, m_hWnd, false, Util::getAppPath() + "FileLists\\", types)) {
		string username;
		if(file.rfind('\\') != string::npos) {
			username = file.substr(file.rfind('\\') + 1);
			if(username.rfind('.') != string::npos) {
				username.erase(username.rfind('.'));
			}
			if(username.length() > 4 && Util::stricmp(username.c_str() + username.length() - 4, ".xml") == 0)
				username.erase(username.length()-4);
			DirectoryListingFrame::openWindow(file, ClientManager::getInstance()->getUser(username));
		}
	}
	return 0;
}

LRESULT MainFrame::onRefreshFileList(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	ShareManager::getInstance()->setDirty();
	ShareManager::getInstance()->refresh(true);
	return 0;
}

LRESULT MainFrame::onTrayIcon(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
	if (lParam == WM_LBUTTONUP) {
		ShowWindow(SW_SHOW);
		ShowWindow(maximized ? SW_MAXIMIZE : SW_RESTORE);
	}else if(lParam == WM_RBUTTONDOWN || lParam == WM_CONTEXTMENU){ 		
		CPoint pt;
		CMenu mnuTrayMenu;
		mnuTrayMenu.CreatePopupMenu();
		mnuTrayMenu.AppendMenu(MF_STRING, IDC_TRAY_SHOW, CTSTRING(MENU_SHOW));
		mnuTrayMenu.AppendMenu(MF_STRING, IDC_TRAY_QUIT, CTSTRING(MENU_EXIT));
		mnuTrayMenu.AppendMenu(MF_STRING, IDC_OPEN_DOWNLOADS, CTSTRING(MENU_OPEN_DOWNLOADS_DIR));
		GetCursorPos(&pt);
		SetForegroundWindow(m_hWnd); 
		mnuTrayMenu.TrackPopupMenu(TPM_BOTTOMALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,pt.x,pt.y,m_hWnd);
		PostMessage(WM_NULL, 0, 0);
		mnuTrayMenu.SetMenuDefaultItem(0,TRUE);
	} else if(lParam == WM_MOUSEMOVE && ((lastMove + 1000) < GET_TICK()) ) {
		NOTIFYICONDATA nid;
		nid.cbSize = sizeof(NOTIFYICONDATA);
		nid.hWnd = m_hWnd;
		nid.uID = 0;
		nid.uFlags = NIF_TIP;
		_tcsncpy(nid.szTip, ("D: " + Util::formatBytes(DownloadManager::getInstance()->getAverageSpeed()) + "/s (" + 
			Util::toString(DownloadManager::getInstance()->getDownloads()) + ")\r\nU: " +
			Util::formatBytes(UploadManager::getInstance()->getAverageSpeed()) + "/s (" + 
			Util::toString(UploadManager::getInstance()->getUploads()) + ")").c_str(), 64);
		
		::Shell_NotifyIcon(NIM_MODIFY, &nid);
		lastMove = GET_TICK();
	}
	return 0;
}

LRESULT MainFrame::OnViewToolBar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	static BOOL bVisible = TRUE;	// initially visible
	bVisible = !bVisible;
	CReBarCtrl rebar = m_hWndToolBar;
	int nBandIndex = rebar.IdToIndex(ATL_IDW_BAND_FIRST + 1);	// toolbar is 2nd added band
	rebar.ShowBand(nBandIndex, bVisible);
	UISetCheck(ID_VIEW_TOOLBAR, bVisible);
	UpdateLayout();
	return 0;
}

// CDM EXTENSION BEGINS
LRESULT MainFrame::onToggleToolbar(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	static BOOL bVisible = TRUE;	// initially visible
	bVisible = !bVisible;
	CReBarCtrl rebar = m_hWndToolBar;
	int nBandIndex = rebar.IdToIndex(ATL_IDW_BAND_FIRST + 2);	// toolbar is 2nd added band
	rebar.ShowBand(nBandIndex, bVisible);
	UISetCheck(IDC_TOGGLE_TOOLBAR, bVisible);
	UpdateLayout();
	SettingsManager::getInstance()->set(SettingsManager::SHOW_WINAMP_CONTROL, bVisible);
	return 0;
}
// CDM EXTENSION ENDS

LRESULT MainFrame::onFinished(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	FinishedFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onFinishedUploads(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	FinishedULFrame::openWindow();
	return 0;
}

LRESULT MainFrame::onCloseDisconnected(WORD , WORD , HWND , BOOL& ) {
	HubFrame::closeDisconnected();
	return 0;
}

LRESULT MainFrame::onReconnectDisconnected(WORD , WORD , HWND , BOOL& ) {
	HubFrame::reconnectDisconnected();
	return 0;
}
//Gabberworld starts new_svn4x ,125
LRESULT MainFrame::onCloseAllPrivateMessage(WORD , WORD , HWND , BOOL& ) {
	PrivateFrame::onCloseAllPm();
	return 0;
}
LRESULT MainFrame::onCloseAllHubWindows(WORD , WORD , HWND , BOOL& ) {
	HubFrame::onCloseAllHub();
	return 0;
}
LRESULT MainFrame::onClearAllMainChat(WORD , WORD , HWND , BOOL& ) {
	HubFrame::onClearAllMainChat();
	return 0;
}
LRESULT MainFrame::onStopAllHubChecking(WORD , WORD , HWND , BOOL& ) {
	HubFrame::onStopCheckingAll();
	return 0;
}
LRESULT MainFrame::onStartCheckingInAllHub(WORD , WORD , HWND , BOOL& ) {
	HubFrame::onStartCheckingAll();
	return 0;
}
//Gabberworld ends
void MainFrame::on(TimerManagerListener::Second, u_int32_t aTick) throw() {
		int64_t diff = (int64_t)((lastUpdate == 0) ? aTick - 1000 : aTick - lastUpdate);
		int64_t updiff = Socket::getTotalUp() - lastUp;
		int64_t downdiff = Socket::getTotalDown() - lastDown;

		//Govern upload rate && adjust it based on the time-based upload limit
		// CDM EXTENSION BEGINS
		/*if (SETTING(MAX_UPLOAD_SPEED) < 6 && SETTING(MAX_UPLOAD_SPEED) && (2*SETTING(MAX_UPLOAD_SPEED) < SETTING(MAX_DOWNLOAD_SPEED_REAL) || SETTING(MAX_UPLOAD_SPEED) && !SETTING(MAX_DOWNLOAD_SPEED_REAL)))
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL, 2*SETTING(MAX_UPLOAD_SPEED));
		if (SETTING(MAX_UPLOAD_SPEED_TIME) < 6 && SETTING(MAX_UPLOAD_SPEED_TIME) && (2*SETTING(MAX_UPLOAD_SPEED_TIME) < SETTING(MAX_DOWNLOAD_SPEED_REAL_TIME) || SETTING(MAX_UPLOAD_SPEED_TIME) && !SETTING(MAX_DOWNLOAD_SPEED_REAL_TIME)))
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL_TIME, 2*SETTING(MAX_UPLOAD_SPEED_TIME));*/
		if (SETTING(MAX_UPLOAD_SPEED) && SETTING(DOWNLOAD_UPLOAD_RATIO)*SETTING(MAX_UPLOAD_SPEED) < SETTING(MAX_DOWNLOAD_SPEED_REAL) || SETTING(MAX_UPLOAD_SPEED) && !SETTING(MAX_DOWNLOAD_SPEED_REAL))
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL, SETTING(DOWNLOAD_UPLOAD_RATIO)*SETTING(MAX_UPLOAD_SPEED));
		if (SETTING(MAX_UPLOAD_SPEED_TIME) > 0 && SETTING(DOWNLOAD_UPLOAD_RATIO_TIME)*SETTING(MAX_UPLOAD_SPEED_TIME) < SETTING(MAX_DOWNLOAD_SPEED_REAL_TIME) || SETTING(MAX_UPLOAD_SPEED_TIME) && !SETTING(MAX_DOWNLOAD_SPEED_REAL_TIME))
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL_TIME, SETTING(DOWNLOAD_UPLOAD_RATIO_TIME)*SETTING(MAX_UPLOAD_SPEED_TIME));
		// CDM EXTENSION ENDS
		// evil pothead starts
		if (SETTING(DOWNLOAD_UPLOAD_RATIO) > 10)
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL, 1);
		if (SETTING(DOWNLOAD_UPLOAD_RATIO_TIME) > 10)
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL_TIME, 1);
		// evil pothead ends
		time_t currentTime;
		time(&currentTime);
		int currentHour = localtime(&currentTime)->tm_hour;

		int currentSlots = SETTING(SLOTS);		//note current slots. if we change that in the transition send a myinfo.

		if (SETTING(TIME_DEPENDENT_THROTTLE) &&
			((SETTING(BANDWIDTH_LIMIT_START) < SETTING(BANDWIDTH_LIMIT_END) &&
				currentHour >= SETTING(BANDWIDTH_LIMIT_START) && currentHour < SETTING(BANDWIDTH_LIMIT_END)) ||
			(SETTING(BANDWIDTH_LIMIT_START) > SETTING(BANDWIDTH_LIMIT_END) &&
				(currentHour >= SETTING(BANDWIDTH_LIMIT_START) || currentHour < SETTING(BANDWIDTH_LIMIT_END))))
		) {
			//want to keep this out of the upload limiting code proper, where it might otherwise work more naturally
			SettingsManager::getInstance()->set(SettingsManager::MAX_UPLOAD_SPEED_YAY_ANOTHER_LEVEL_OF_INDIRECTION_GO_GO_GO, SETTING(MAX_UPLOAD_SPEED_TIME));
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL_A_PARALLEL_LEVEL_OF_HOPEFULLY_USEFUL_INDIRECTION_IN_AN_ABSURDLY_LONG_IDENTIFIER, SETTING(MAX_DOWNLOAD_SPEED_REAL_TIME));
			SettingsManager::getInstance()->set(SettingsManager::SLOTS, SETTING(WATCH_THE_DUCKLINGS_HOP_HOP_SKIP));
		} else {
			SettingsManager::getInstance()->set(SettingsManager::MAX_UPLOAD_SPEED_YAY_ANOTHER_LEVEL_OF_INDIRECTION_GO_GO_GO, SETTING(MAX_UPLOAD_SPEED));
			SettingsManager::getInstance()->set(SettingsManager::MAX_DOWNLOAD_SPEED_REAL_A_PARALLEL_LEVEL_OF_HOPEFULLY_USEFUL_INDIRECTION_IN_AN_ABSURDLY_LONG_IDENTIFIER, SETTING(MAX_DOWNLOAD_SPEED_REAL));
			SettingsManager::getInstance()->set(SettingsManager::SLOTS, SETTING(THE_DUCKLINGS_HATE_YOU_TOO));
		}

		if (SETTING(SLOTS) != currentSlots) ClientManager::getInstance()->infoUpdated();

		StringList* str = new StringList();
		str->push_back(Util::getAway() ? STRING(AWAY) : "");
		str->push_back("H: " + Client::getCounts());
		str->push_back(STRING(SLOTS) + ": " + Util::toString(SETTING(SLOTS) - UploadManager::getInstance()->getRunning()) + '/' + Util::toString(SETTING(SLOTS)));
//		str->push_back("D: " + Util::formatBytes(Socket::getTotalDown()));
//		str->push_back("U: " + Util::formatBytes(Socket::getTotalUp()));
//		str->push_back("D Lim: " + Util::formatBytes(SETTING(MAX_DOWNLOAD_SPEED_REAL_A_PARALLEL_LEVEL_OF_HOPEFULLY_USEFUL_INDIRECTION_IN_AN_ABSURDLY_LONG_IDENTIFIER)*1024I64) + "/s");
//		str->push_back("U Lim: " + Util::formatBytes(SETTING(MAX_UPLOAD_SPEED_YAY_ANOTHER_LEVEL_OF_INDIRECTION_GO_GO_GO)*1024I64) + "/s");
		str->push_back("D: " + Util::formatBytes(downdiff*1000I64/diff) + "/s (" + Util::toString(DownloadManager::getInstance()->getDownloads()) + ")");
		str->push_back("U: " + Util::formatBytes(updiff*1000I64/diff) + "/s (" + Util::toString(UploadManager::getInstance()->getUploads()) + ")");
		// pothead extension starts (r2 code) #12 svn42
//		str->push_back("Uptime: " + Util::formatTime(GET_TIME() - WinUtil::startTime, true));
		//str->push_back("Mem: " + Util::getMemoryUsage());
		str->push_back(Util::getLocalIp());
		// pothead extension ends
		PostMessage(WM_SPEAKER, STATS, (LPARAM)str);
		SettingsManager::getInstance()->set(SettingsManager::TOTAL_UPLOAD, SETTING(TOTAL_UPLOAD) + updiff);
		SettingsManager::getInstance()->set(SettingsManager::TOTAL_DOWNLOAD, SETTING(TOTAL_DOWNLOAD) + downdiff);
		lastUpdate = aTick;
		lastUp = Socket::getTotalUp();
		lastDown = Socket::getTotalDown();
		if(currentPic != SETTING(BACKGROUND_IMAGE)) { currentPic = SETTING(BACKGROUND_IMAGE); m_PictureWindow.Load(currentPic.c_str()); }
}

// HttpConnectionListener
void MainFrame::on(HttpConnectionListener::Complete, HttpConnection* conn, string const& /*aLine*/) throw() {
	onHttpComplete(conn);
}
void MainFrame::on(HttpConnectionListener::Data, HttpConnection* /*conn*/, const BYTE* buf, int len) throw() {
		versionInfo += string((const char*)buf, len);
}

void MainFrame::on(QueueManagerListener::Types type, QueueItem* qi) throw() {
	if(type == QueueManagerListener::FINISHED) {
		if(qi->isSet(QueueItem::FLAG_CLIENT_VIEW)) {
			if(qi->isSet(QueueItem::FLAG_USER_LIST)) {
				// This is a file listing, show it...

				DirectoryListInfo* i = new DirectoryListInfo();
				i->file = qi->getListName();
				i->user = qi->getCurrent()->getUser();
				i->start = qi->getSearchString();

				PostMessage(WM_SPEAKER, DOWNLOAD_LISTING, (LPARAM)i);
			} else if(qi->isSet(QueueItem::FLAG_TEXT)) {
				PostMessage(WM_SPEAKER, VIEW_FILE_AND_DELETE, (LPARAM) new string(qi->getTarget()));
			}
		}
	}
}
//Sulan start svn 46
void MainFrame::on(VersionManagerListener::Types type, const string& /*aName*/, const string& /*aVersion*/, const string& /*aAddy*/, const string& /*aMessage*/) throw() {
	if(type == VersionManagerListener::CLIENT_UPDATED && BOOLSETTING(POPUNDER_ALERT)){
		PostMessage(WM_SPEAKER,OPEN_CVF);
	}
}
//End
// pothead starts svn79
LRESULT MainFrame::onAppCommand(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled) {
	if(GET_APPCOMMAND_LPARAM(lParam) == APPCOMMAND_BROWSER_FORWARD)
		ctrlTab.SwitchTo();
	if(GET_APPCOMMAND_LPARAM(lParam) == APPCOMMAND_BROWSER_BACKWARD)
		ctrlTab.SwitchTo(false);
	bHandled = FALSE;
	return TRUE;
}

LRESULT MainFrame::onTabForward(UINT /*uMsg*/, WPARAM /*wParam*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	ctrlTab.SwitchTo();
	return 0;
}

LRESULT MainFrame::onTabBackward(UINT /*uMsg*/, WPARAM /*wParam*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	ctrlTab.SwitchTo(false);
	return 0;
}
// pothead ends
// pothead starts svn171 (dc++ code)
LRESULT MainFrame::onQuickConnect(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/){
	LineDlg dlg;
	dlg.description = STRING(HUB_ADDRESS);
	dlg.title = STRING(QUICK_CONNECT);
	if(dlg.DoModal(m_hWnd) == IDOK){
		if(SETTING(NICK).empty())
			return 0;

		string tmp = dlg.line;
		// Strip out all the spaces
		string::size_type i;
		while((i = tmp.find(' ')) != string::npos)
			tmp.erase(i, 1);

		HubFrame::openWindow(tmp);
	}
	return 0;
}
//Gabberworld starts new_svn4x (r2 code)
LRESULT MainFrame::onGetTTH(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) {
	string file = Util::getAppPath() + "*.*";
 	if(WinUtil::browseFile(file, m_hWnd, false) == IDOK) {
		string hash = HashManager::getInstance()->hasher.getTTfromFile(file).getRoot().toBase32();
	
		CInputBox ibox(m_hWnd);
		WIN32_FIND_DATA data;
		FindFirstFile(file.c_str(), &data);
		string magnetlink = "magnet:?xt=urn:tree:tiger:"+hash+"&dn=" + Util::encodeURI(Util::getFileName(file));
		ibox.DoModal(_T("Tiger Tree Hash"), file.c_str(), hash.c_str(), magnetlink.c_str());
		} 
	return 0;
}
//Gabberworld ends
void MainFrame::startUPnP() {
	stopUPnP();

	if( SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE && SETTING(USE_UPNP)) {
		UPnP_TCPConnection = new UPnP( Util::getLocalIp(), "TCP", APPNAME " Download Port (" + Util::toString(ConnectionManager::getInstance()->getPort()) + " TCP)", ConnectionManager::getInstance()->getPort() );
		UPnP_UDPConnection = new UPnP( Util::getLocalIp(), "UDP", APPNAME " Search Port (" + Util::toString(SearchManager::getInstance()->getPort()) + " UDP)", SearchManager::getInstance()->getPort() );

		if ( FAILED(UPnP_UDPConnection->OpenPorts()) || FAILED(UPnP_TCPConnection->OpenPorts()) )
		{
			LogManager::getInstance()->message("Failed to create portmappings");
			MessageBox(_T("Failed to create port mappings. Please set up your NAT yourself, or dispable UPnP on DCDM settings page."), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_OK | MB_ICONWARNING);

			// We failed! thus reset the objects
			delete UPnP_TCPConnection;
			delete UPnP_UDPConnection;
			UPnP_TCPConnection = UPnP_UDPConnection = NULL;
		}
		else
		{
			if(!BOOLSETTING(NO_IP_OVERRIDE)) {
				// now lets configure the external IP (connect to me) address
				string ExternalIP = UPnP_TCPConnection->GetExternalIP();
				if ( !ExternalIP.empty() ) {
					// woohoo, we got the external IP from the UPnP framework
					SettingsManager::getInstance()->set(SettingsManager::SERVER, ExternalIP );
					SettingsManager::getInstance()->set(SettingsManager::SEARCH_SERVER, ExternalIP );
				} else {
					//:-( Looks like we have to rely on the user setting the external IP manually
					// no need to do cleanup here because the mappings work
					LogManager::getInstance()->message("Failed to get external IP via UPnP. Please set it yourself.");
					MessageBox(_T("Failed to get external IP via UPnP. Please set it yourself."), _T(APPNAME) _T(" ") _T(VERSIONSTRING), MB_OK | MB_ICONWARNING);
				}
			}
		}
	}
}

void MainFrame::stopUPnP() {
	// Just check if the port mapping objects are initialized (NOT NULL)
	if ( UPnP_TCPConnection != NULL )
	{
		if (FAILED(UPnP_TCPConnection->ClosePorts()) )
		{
			LogManager::getInstance()->message("Failed to remove port mappings");
		}
		delete UPnP_TCPConnection;
	}
	if ( UPnP_UDPConnection != NULL )
	{
		if (FAILED(UPnP_UDPConnection->ClosePorts()) )
		{
			LogManager::getInstance()->message("Failed to remove port mappings");
		}
		delete UPnP_UDPConnection;
	}
	// Not sure this is required (i.e. Objects are checked later in execution)
	// But its better being on the save side :P
	UPnP_TCPConnection = UPnP_UDPConnection = NULL;
}
// pothead ends
/**
 * @file
 * $Id: MainFrm.cpp 331 2005-09-02 11:13:58Z sulan $
 */